All databases are encrypted. KeePass always encrypts the whole database, i.e. not
only your passwords. Your usernames, notes, even the entry times and UUIDs, etc. are
encrypted, too.
The databases are encrypted using one of the following two block ciphers:
Cipher
Block size
Key size
Advanced Encryption Standard (AES / Rijndael)
128 bits
256 bits
Twofish
128 bits
256 bits
These algorithms are well-known, well-analyzed and
generally considered to be secure by the cryptographic community (see
[1]
for comments by the NIST on AES for example).
The block ciphers are used in the CBC (cipher-block chaining) block cipher mode.
For both algorithms, a 128-bit initialization vector (IV) is generated randomly
each time you save the database.
Hashing
In order to generate the 256-bit key for the ciphers the secure hash
algorithm SHA-256 is used. Please
note that the recently discovered attack against SHA-1
[2] doesn't affect the security
of SHA-256. SHA-256 is still considered as being secure
[3].
The user key (the passphrase the user enters
or the byte string in the key-file) plus an 128-bit random salt is hashed using SHA-256.
This random salt prevents attacks that are based on pre-computed hashes.
When using both master key and key-disk together, the final key is
derived as follows: SHA-256(SHA-256(master password), key-file contents), i.e.
the hash of the master password is concatenated with the key-file bytes and
the resulting byte string is hashed with SHA-256 again. If the key-file contents
aren't exactly 32 bytes (256 bits), they are hashed with SHA-256, too, to form
a 256-bit key, i.e. the formula above changes to: SHA-256(SHA-256(master password),
SHA-256(key-file contents)).
Random number generation
We need to generate several 'random' bytes (for the IV, the master key salt,
etc.). For this,
several pseudo-random sources are used: current tick count, performance counter,
system date/time, mouse cursor position, memory status (free virtual memory,
etc.), active window, clipboard owner, various process and thread IDs, various window
focus handles (active window, desktop, ...), window message stack, process heap
status, process startup information and several system information structures.
This pseudo-random data is collected in a random pool. To generate 16 random bytes,
the pool is hashed (SHA-256) with a counter to form the final 16 random bytes. The
counter is increased after 16 generated bytes, this way we can produce as many secure
random bytes as we need.
Protection against dictionary and guessing attacks
KeePass offers some protection against guessing and dictionary attacks.
This is only needed when using master passwords, key-disks don't need this, they
are more secure anyway [4].
You
can't really prevent dictionary and guessing attacks, nothing prevents an attacker to just try
all possible keys and look if the database decrypts. But what we can do (and
KeePass does) is to make it harder: by adding a constant time factor to the
key initialization, we can make them as hard as we want [5][6].
To generate the
'final' 256-bit key that is used for the block cipher, KeePass first hashes the
users key (SHA-256), encrypts the result N times using the Advanced Encryption
Standard (AES) and then hashes it again (SHA-256). Since the AES transformations
aren't pre-computable, an attacker has to perform all the encryptions, too, otherwise
he cannot try and see if the key he is currently trying is correct. The key used
for the AES transformation is randomly generated and stored in the database
header (this prevents pre-computing the AES transformations, although this
is almost impossible anyway).
By default, KeePass
sets N to 6000 encryption 'rounds' (full encryptions are meant, has nothing
to do with the internal encryption rounds of AES). This has been done in order to
provide compatibility to the PocketPC version (PocketPC processors are slower,
therefore the key computation takes longer). Nothing prevents you from setting
this to a much larger value (you can set it in the database options dialog), if
you accept a one-second delay on your PC when opening a KeePass database, you
can even set it to a few 100.000s. Think about this: an attacker now also needs
much longer to try a key. If it takes him one second for one key, he can almost
forget any dictionary and guessing attacks.
In-memory passwords protection
While KeePass is running, your passwords are encrypted using a 'session key'
(randomly generated at startup).
This means, that even if you would dump the whole KeePass process memory to disk,
you couldn't find the passwords (at least not in plain text). Note that this only
applies to the passwords field, not to the usernames, etc. because of speed
reasons. When you want to copy a password to the clipboard for example, KeePass
first decrypts the password field using the session key, copies it to the clipboard
and immediately re-encrypts it using the session key. Here, ARC4 is used as encryption
algorithm, the session key has a fixed size of 12 bytes.
KeePass securely erases all security-critical memory when it's not needed any more, i.e.
it overwrites those memory areas with random data before zeroing and releasing it
(this applies to all security-critical memory, not only the passwords field).
Locking the workspace
What happens when you lock the workspace? Why are you sometimes prompted to
save the database first? It's simple: locking the workspace just closes the
database completely, but remembers the last view settings (i.e. which group and entry you
selected, list position, etc.). This provides maximum security (unlocking the
workspace is as hard as opening the database the normal way) and prevents
data-loss (what if your computer crashes while the workspace is locked?).
Plugin security
A separate page exists about the security of plugins:
Plugin Security.
Self-tests
Each time you start KeePass, the program will perform a quick self-test to see
whether the block ciphers and the hash are compiled correctly and pass
their test-vectors. If one of the algorithms doesn't pass its test-vector,
KeePass will show you a security exception message box at startup.